package com.wrupple.muba.catalogs.client.module.services.logic.impl;

import java.util.Collection;

import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.core.client.JsArray;
import com.google.gwt.json.client.JSONNumber;
import com.google.gwt.json.client.JSONValue;
import com.wrupple.muba.common.client.FieldConversionStrategy;
import com.wrupple.muba.common.client.JSOHelper;

public class FieldConversionStrategyImpl implements FieldConversionStrategy {
	boolean numberAsString;
	boolean nullAsEmptyString;
	
	//system version
	boolean emptyStringsAsNull;
	private boolean zeroAsNull;
	
	@Override
	public Object userVersion(String attr, JavaScriptObject elem) {
		return objectify(elem, attr);
	}

	@Override
	public Object systemVersion(Object userVersion) {
		return objectify(userVersion);
	}

	

	private Object objectify(Object value) {
		if (value == null) {
			return getNullObject();
		}  else if (value instanceof Collection) {
			Collection<Object> collection = (Collection<Object>) value;
			return getSendableCollection(collection);
		}  else if (value instanceof Number) {
			Number v = (Number) value;
			return v.doubleValue();
		}else if(value instanceof String){
			String v = (String) value;
			v=v.trim();
			return getSendableString(v);
		} else {
			return value;
		}
	}

	private Object getSendableString(String v) {
		if(emptyStringsAsNull){
			if(v.length()==0){
				return null;
			}
		}
		return v;
	}

	private JavaScriptObject getSendableCollection(Collection<Object> collection) {
		return JSOHelper.convertToJavaScriptArray(collection.toArray());
	}

	private  Object objectify(JavaScriptObject elem,
			String attr) {
		JSONValue value = JSOHelper.getObjectValue(attr, elem);
		if (value == null) {
			return getNullObject();
		} else if (value.isNull() != null) {
			return getNullObject();
		} else if (value.isArray() != null) {
			JsArray<JavaScriptObject> arr = value.isArray().getJavaScriptObject().cast();
			return getArrayValue(arr);
		} else if (value.isObject() != null) {
			JavaScriptObject jso = value.isObject().getJavaScriptObject();
			return getJSOValue(jso);
		} else if (value.isBoolean() != null) {
			boolean bool = value.isBoolean().booleanValue();
			return getBoolanValue(bool);
		} else if (value.isNumber() != null) {
			JSONNumber jsonNumber = value.isNumber();
			return getDoubleValue(jsonNumber);
		} else {
			try {
				String string =value.isString().stringValue() ;
				return getStringValue(string);
			} catch (Exception e) {
				return getDefaultValue(value);
			}
		}
	}

	protected Object getDefaultValue(JSONValue value) {
		return value.toString();
	}

	protected Object getStringValue(String string) {
		//TODO parse Double?
		return string.trim();
	}

	protected Object getDoubleValue(JSONNumber regreso) {
		if(numberAsString){
			return regreso.toString();
		}else{
			return regreso.doubleValue();
		}
	}

	protected Object getBoolanValue(boolean bool) {
		return bool;
	}

	protected Object getJSOValue(JavaScriptObject jso) {
		return jso;
	}

	protected Object getArrayValue(JsArray<JavaScriptObject> arr) {
		return arr;
	}

	protected Object getNullObject() {
		if(nullAsEmptyString){
			return "";
		}else{
			return null;
		}
	}

	public boolean isNumberAsString() {
		return numberAsString;
	}

	@Override
	public void setNumberAsString(boolean numberAsString) {
		this.numberAsString = numberAsString;
	}

	public boolean isNullAsEmptyString() {
		return nullAsEmptyString;
	}

	@Override
	public void setNullAsEmptyString(boolean nullAsEmptyString) {
		this.nullAsEmptyString = nullAsEmptyString;
	}

	public boolean isEmptyStringsAsNull() {
		return emptyStringsAsNull;
	}

	@Override
	public void setEmptyStringsAsNull(boolean emptyStringsAsNull) {
		this.emptyStringsAsNull = emptyStringsAsNull;
	}

	public boolean isZeroAsNull() {
		return zeroAsNull;
	}
	@Override
	public void setZeroAsNull(boolean zeroAsNull) {
		this.zeroAsNull = zeroAsNull;
	}
	
	
}
